# code to load packages
library(tidyverse)
library(tidymodels)
library(knitr)
library(dplyr)
library(ggplot2)
library(patchwork)
library(corrplot)
corrplot 0.94 loaded
#baseR
auto <- read_csv("data/autopod_data.csv")
New names:
• `notes` -> `notes...22`
• `notes` -> `notes...60`
• `` -> `...98`
Rows: 582 Columns: 122
── Column specification ─────────────────────────────────────────────────────────
Delimiter: ","
chr (108): Collector, Higher taxon, Taxon, miss mC, miss mT, miss  man-D, mis...
dbl   (2): radius L, Ulna L
lgl  (12): m2-5 av, hpp2-5 av, hmp2-5 av, hdp2-5 av, notes...60, fpp2-5 av, f...

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
#Set hms as numeric 
auto$hm1 <- as.numeric(as.character(auto$hm1))
Warning: NAs introduced by coercion
auto$hm2 <- as.numeric(as.character(auto$hm2))
Warning: NAs introduced by coercion
auto$hm3 <- as.numeric(as.character(auto$hm3))
Warning: NAs introduced by coercion
auto$hm4 <- as.numeric(as.character(auto$hm4))
Warning: NAs introduced by coercion
auto$hm5 <- as.numeric(as.character(auto$hm5))
Warning: NAs introduced by coercion
#Set hpps as numeric 
auto$hpp1 <- as.numeric(as.character(auto$hpp1))
Warning: NAs introduced by coercion
auto$hpp2 <- as.numeric(as.character(auto$hpp2))
Warning: NAs introduced by coercion
auto$hpp3 <- as.numeric(as.character(auto$hpp3))
Warning: NAs introduced by coercion
auto$hpp4 <- as.numeric(as.character(auto$hpp4))
Warning: NAs introduced by coercion
auto$hpp5 <- as.numeric(as.character(auto$hpp5))
Warning: NAs introduced by coercion
#remove NAs
autoclean <- auto %>%
  filter(complete.cases(hm1, hm2, hm3, hm4, hm5, hpp1, hpp2, hpp3, hpp4, hpp5))
#avg hand metatarsals for each higher taxa

hm_avg <- autoclean |>
  group_by(`Higher taxon`) |>
  summarize(average_hm1 = mean(hm1, na.rm = TRUE),
            average_hm2 = mean(hm2, na.rm = TRUE),
            average_hm3 = mean(hm3, na.rm = TRUE),
            average_hm4 = mean(hm4, na.rm = TRUE),
            average_hm5 = mean(hm5, na.rm = TRUE)
            )
print(hm_avg)
#avg proximal phalanges for each higher taxa

hpp_avg <- autoclean |>
  group_by(`Higher taxon`) |>
  summarize(average_hpp1 = mean(hpp1, na.rm = TRUE),
            average_hpp2 = mean(hpp2, na.rm = TRUE),
            average_hpp3 = mean(hpp3, na.rm = TRUE),
            average_hpp4 = mean(hpp4, na.rm = TRUE),
            average_hpp5 = mean(hpp5, na.rm = TRUE)
            )
print(hpp_avg)
#get total digit lengths 

autoclean$total_digit1 <- autoclean$hm1 + autoclean$hpp1
autoclean$total_digit2 <- autoclean$hm2 + autoclean$hpp2
autoclean$total_digit3 <- autoclean$hm3 + autoclean$hpp3
autoclean$total_digit4 <- autoclean$hm4 + autoclean$hpp4
autoclean$total_digit5 <- autoclean$hm5 + autoclean$hpp5

head(autoclean)
NA
#AVG DIGIT LENGTHS
avg_digit_lengths <- hm_avg |>
  full_join(hpp_avg, by = "Higher taxon") |>

  mutate(
      avg_digit1 = hm_avg$average_hm1 + hpp_avg$average_hpp1,
    avg_digit2 = hm_avg$average_hm2 + hpp_avg$average_hpp2,
    avg_digit3 = hm_avg$average_hm3 + hpp_avg$average_hpp3,
    avg_digit4 = hm_avg$average_hm4 + hpp_avg$average_hpp4,
    avg_digit5 = hm_avg$average_hm5 + hpp_avg$average_hpp5
    ) |>
    select(`Higher taxon`, avg_digit1, avg_digit2, avg_digit3, avg_digit4, avg_digit5)

avg_digit_lengths
#EXPLORING COVARIATION
# biplots for comparing digit lengths

#to calc rsquared 
r_squared <- function(x, y) {
  model <- lm(y ~ x)
  summary(model)$r.squared
}

pairs <- list(
  c("total_digit1", "total_digit2"),
  c("total_digit1", "total_digit3"),
  c("total_digit1", "total_digit4"),
  c("total_digit1", "total_digit5"),
  c("total_digit2", "total_digit3"),
  c("total_digit2", "total_digit4"),
  c("total_digit2", "total_digit5"),
  c("total_digit3", "total_digit4"),
  c("total_digit3", "total_digit5"),
  c("total_digit4", "total_digit5")
)

for (pair in pairs) {
  x <- autoclean[[pair[1]]]
  y <- autoclean[[pair[2]]]
  r_squared <- calculate_r_squared(x, y)
  p <- ggplot(autoclean, aes_string(x = pair[1], y = pair[2])) +
    geom_point() +
    labs(x = pair[1], y = pair[2], title = paste("Biplot of", pair[1], "and", pair[2]), subtitle = paste("R^2 =", r_squared)) +
    theme_minimal()
  print(p)
}

#correlation matrix for total digit lengths
correlation_matrix <- cor(autoclean[, c("total_digit1", "total_digit2", "total_digit3", "total_digit4", "total_digit5")])
print(correlation_matrix)
             total_digit1 total_digit2 total_digit3 total_digit4 total_digit5
total_digit1    1.0000000    0.9566183    0.9565192    0.9634344    0.9664044
total_digit2    0.9566183    1.0000000    0.9791062    0.9725032    0.9686648
total_digit3    0.9565192    0.9791062    1.0000000    0.9941848    0.9786560
total_digit4    0.9634344    0.9725032    0.9941848    1.0000000    0.9928006
total_digit5    0.9664044    0.9686648    0.9786560    0.9928006    1.0000000
corrplot(correlation_matrix, method = "color", addCoef.col = "black", tl.col = "black", tl.srt = 45)


# Function to calculate R^2
calc_r_squared <- function(x, y) {
  model <- lm(y ~ x)
  summary(model)$r.squared
}

# Create pairs of digit lengths
pairs <- list(
  c("total_digit1", "total_digit2"),
  c("total_digit1", "total_digit3"),
  c("total_digit1", "total_digit4"),
  c("total_digit1", "total_digit5"),
  c("total_digit2", "total_digit3"),
  c("total_digit2", "total_digit4"),
  c("total_digit2", "total_digit5"),
  c("total_digit3", "total_digit4"),
  c("total_digit3", "total_digit5"),
  c("total_digit4", "total_digit5")
)

# Get unique taxa
unique_taxa <- unique(autoclean$`Higher taxon`)

# for each higher taxa 
for (taxon in unique_taxa) {
  # filter for the current higher taxon
  taxa_data <- autoclean[autoclean$`Higher taxon` == taxon, ]
  
  # going thru each digit pair 
  for (pair in pairs) {
    x <- taxa_data[[pair[1]]]
    y <- taxa_data[[pair[2]]]
    
    # get r^2
    r_squared <- calc_r_squared(x, y)
    
    # actual plot
    p <- ggplot(taxa_data, aes_string(x = pair[1], y = pair[2])) +
      geom_point(color = "#0096FF", alpha = 0.6, size = 3) +
      labs(
        x = pair[1],
        y = pair[2],
        title = paste("Biplot of", pair[1], "and", pair[2], "for", taxon),
        subtitle = paste("R^2 =", round(r_squared, 3))
      ) +
      theme_minimal() +
      theme(
        plot.title = element_text(size = 12, face = "bold", color = "#0096FF"),
        plot.subtitle = element_text(size = 10, color = "black"),
        axis.title.x = element_text(size = 10, face = "bold"),
        axis.title.y = element_text(size = 10, face = "bold"),
        panel.background = element_rect(fill = "#FFF1F3"),  
        panel.grid.major = element_line(color = "white"), 
        panel.grid.minor = element_line(color = "white")
      )
    print(p)
  }
}

unique_taxa <- unique(autoclean$`Higher taxon`)

for (taxon in unique_taxa) {
  taxa_data <- autoclean[autoclean$`Higher taxon` == taxon, ]

  correlation_matrix <- cor(autoclean[, c("total_digit1", "total_digit2", 
                                          "total_digit3", "total_digit4", 
                                          "total_digit5")])
  print(taxon)
  print(correlation_matrix)
  corrplot(correlation_matrix, method = "color", addCoef.col = "black", tl.col = 
             "black", tl.srt = 45,   title=taxon,    mar=c(0,0,1,0) )
}
[1] "Hominoidea"
             total_digit1 total_digit2 total_digit3 total_digit4 total_digit5
total_digit1    1.0000000    0.9566183    0.9565192    0.9634344    0.9664044
total_digit2    0.9566183    1.0000000    0.9791062    0.9725032    0.9686648
total_digit3    0.9565192    0.9791062    1.0000000    0.9941848    0.9786560
total_digit4    0.9634344    0.9725032    0.9941848    1.0000000    0.9928006
total_digit5    0.9664044    0.9686648    0.9786560    0.9928006    1.0000000
[1] "Cercopithecoidea"
             total_digit1 total_digit2 total_digit3 total_digit4 total_digit5
total_digit1    1.0000000    0.9566183    0.9565192    0.9634344    0.9664044
total_digit2    0.9566183    1.0000000    0.9791062    0.9725032    0.9686648
total_digit3    0.9565192    0.9791062    1.0000000    0.9941848    0.9786560
total_digit4    0.9634344    0.9725032    0.9941848    1.0000000    0.9928006
total_digit5    0.9664044    0.9686648    0.9786560    0.9928006    1.0000000

[1] "Dermoptera"
             total_digit1 total_digit2 total_digit3 total_digit4 total_digit5
total_digit1    1.0000000    0.9566183    0.9565192    0.9634344    0.9664044
total_digit2    0.9566183    1.0000000    0.9791062    0.9725032    0.9686648
total_digit3    0.9565192    0.9791062    1.0000000    0.9941848    0.9786560
total_digit4    0.9634344    0.9725032    0.9941848    1.0000000    0.9928006
total_digit5    0.9664044    0.9686648    0.9786560    0.9928006    1.0000000

[1] "Platyrrhini"
             total_digit1 total_digit2 total_digit3 total_digit4 total_digit5
total_digit1    1.0000000    0.9566183    0.9565192    0.9634344    0.9664044
total_digit2    0.9566183    1.0000000    0.9791062    0.9725032    0.9686648
total_digit3    0.9565192    0.9791062    1.0000000    0.9941848    0.9786560
total_digit4    0.9634344    0.9725032    0.9941848    1.0000000    0.9928006
total_digit5    0.9664044    0.9686648    0.9786560    0.9928006    1.0000000

[1] "Scandentia"
             total_digit1 total_digit2 total_digit3 total_digit4 total_digit5
total_digit1    1.0000000    0.9566183    0.9565192    0.9634344    0.9664044
total_digit2    0.9566183    1.0000000    0.9791062    0.9725032    0.9686648
total_digit3    0.9565192    0.9791062    1.0000000    0.9941848    0.9786560
total_digit4    0.9634344    0.9725032    0.9941848    1.0000000    0.9928006
total_digit5    0.9664044    0.9686648    0.9786560    0.9928006    1.0000000

[1] "Strepsirrhini"
             total_digit1 total_digit2 total_digit3 total_digit4 total_digit5
total_digit1    1.0000000    0.9566183    0.9565192    0.9634344    0.9664044
total_digit2    0.9566183    1.0000000    0.9791062    0.9725032    0.9686648
total_digit3    0.9565192    0.9791062    1.0000000    0.9941848    0.9786560
total_digit4    0.9634344    0.9725032    0.9941848    1.0000000    0.9928006
total_digit5    0.9664044    0.9686648    0.9786560    0.9928006    1.0000000

[1] "Tarsiiforms"
             total_digit1 total_digit2 total_digit3 total_digit4 total_digit5
total_digit1    1.0000000    0.9566183    0.9565192    0.9634344    0.9664044
total_digit2    0.9566183    1.0000000    0.9791062    0.9725032    0.9686648
total_digit3    0.9565192    0.9791062    1.0000000    0.9941848    0.9786560
total_digit4    0.9634344    0.9725032    0.9941848    1.0000000    0.9928006
total_digit5    0.9664044    0.9686648    0.9786560    0.9928006    1.0000000

LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3J9CiMgY29kZSB0byBsb2FkIHBhY2thZ2VzCmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KHRpZHltb2RlbHMpCmxpYnJhcnkoa25pdHIpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShwYXRjaHdvcmspCmxpYnJhcnkoY29ycnBsb3QpCgojYmFzZVIKYGBgCgpgYGB7cn0KYXV0byA8LSByZWFkX2NzdigiZGF0YS9hdXRvcG9kX2RhdGEuY3N2IikKCiNTZXQgaG1zIGFzIG51bWVyaWMgCmF1dG8kaG0xIDwtIGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKGF1dG8kaG0xKSkKYXV0byRobTIgPC0gYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoYXV0byRobTIpKQphdXRvJGhtMyA8LSBhcy5udW1lcmljKGFzLmNoYXJhY3RlcihhdXRvJGhtMykpCmF1dG8kaG00IDwtIGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKGF1dG8kaG00KSkKYXV0byRobTUgPC0gYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoYXV0byRobTUpKQoKI1NldCBocHBzIGFzIG51bWVyaWMgCmF1dG8kaHBwMSA8LSBhcy5udW1lcmljKGFzLmNoYXJhY3RlcihhdXRvJGhwcDEpKQphdXRvJGhwcDIgPC0gYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoYXV0byRocHAyKSkKYXV0byRocHAzIDwtIGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKGF1dG8kaHBwMykpCmF1dG8kaHBwNCA8LSBhcy5udW1lcmljKGFzLmNoYXJhY3RlcihhdXRvJGhwcDQpKQphdXRvJGhwcDUgPC0gYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoYXV0byRocHA1KSkKYGBgCgoKYGBge3J9CiNyZW1vdmUgTkFzCmF1dG9jbGVhbiA8LSBhdXRvICU+JQogIGZpbHRlcihjb21wbGV0ZS5jYXNlcyhobTEsIGhtMiwgaG0zLCBobTQsIGhtNSwgaHBwMSwgaHBwMiwgaHBwMywgaHBwNCwgaHBwNSkpCgpgYGAKCmBgYHtyfQojYXZnIGhhbmQgbWV0YXRhcnNhbHMgZm9yIGVhY2ggaGlnaGVyIHRheGEKCmhtX2F2ZyA8LSBhdXRvY2xlYW4gfD4KICBncm91cF9ieShgSGlnaGVyIHRheG9uYCkgfD4KICBzdW1tYXJpemUoYXZlcmFnZV9obTEgPSBtZWFuKGhtMSwgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgYXZlcmFnZV9obTIgPSBtZWFuKGhtMiwgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgYXZlcmFnZV9obTMgPSBtZWFuKGhtMywgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgYXZlcmFnZV9obTQgPSBtZWFuKGhtNCwgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgYXZlcmFnZV9obTUgPSBtZWFuKGhtNSwgbmEucm0gPSBUUlVFKQogICAgICAgICAgICApCnByaW50KGhtX2F2ZykKYGBgCmBgYHtyfQojYXZnIHByb3hpbWFsIHBoYWxhbmdlcyBmb3IgZWFjaCBoaWdoZXIgdGF4YQoKaHBwX2F2ZyA8LSBhdXRvY2xlYW4gfD4KICBncm91cF9ieShgSGlnaGVyIHRheG9uYCkgfD4KICBzdW1tYXJpemUoYXZlcmFnZV9ocHAxID0gbWVhbihocHAxLCBuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICBhdmVyYWdlX2hwcDIgPSBtZWFuKGhwcDIsIG5hLnJtID0gVFJVRSksCiAgICAgICAgICAgIGF2ZXJhZ2VfaHBwMyA9IG1lYW4oaHBwMywgbmEucm0gPSBUUlVFKSwKICAgICAgICAgICAgYXZlcmFnZV9ocHA0ID0gbWVhbihocHA0LCBuYS5ybSA9IFRSVUUpLAogICAgICAgICAgICBhdmVyYWdlX2hwcDUgPSBtZWFuKGhwcDUsIG5hLnJtID0gVFJVRSkKICAgICAgICAgICAgKQpwcmludChocHBfYXZnKQpgYGAKCmBgYHtyfQojZ2V0IHRvdGFsIGRpZ2l0IGxlbmd0aHMgCgphdXRvY2xlYW4kdG90YWxfZGlnaXQxIDwtIGF1dG9jbGVhbiRobTEgKyBhdXRvY2xlYW4kaHBwMQphdXRvY2xlYW4kdG90YWxfZGlnaXQyIDwtIGF1dG9jbGVhbiRobTIgKyBhdXRvY2xlYW4kaHBwMgphdXRvY2xlYW4kdG90YWxfZGlnaXQzIDwtIGF1dG9jbGVhbiRobTMgKyBhdXRvY2xlYW4kaHBwMwphdXRvY2xlYW4kdG90YWxfZGlnaXQ0IDwtIGF1dG9jbGVhbiRobTQgKyBhdXRvY2xlYW4kaHBwNAphdXRvY2xlYW4kdG90YWxfZGlnaXQ1IDwtIGF1dG9jbGVhbiRobTUgKyBhdXRvY2xlYW4kaHBwNQoKaGVhZChhdXRvY2xlYW4pCgpgYGAKYGBge3J9CiNBVkcgRElHSVQgTEVOR1RIUwoKYXZnX2RpZ2l0X2xlbmd0aHMgPC0gaG1fYXZnIHw+CiAgZnVsbF9qb2luKGhwcF9hdmcsIGJ5ID0gIkhpZ2hlciB0YXhvbiIpIHw+CgogIG11dGF0ZSgKICAgICAgYXZnX2RpZ2l0MSA9IGhtX2F2ZyRhdmVyYWdlX2htMSArIGhwcF9hdmckYXZlcmFnZV9ocHAxLAogICAgYXZnX2RpZ2l0MiA9IGhtX2F2ZyRhdmVyYWdlX2htMiArIGhwcF9hdmckYXZlcmFnZV9ocHAyLAogICAgYXZnX2RpZ2l0MyA9IGhtX2F2ZyRhdmVyYWdlX2htMyArIGhwcF9hdmckYXZlcmFnZV9ocHAzLAogICAgYXZnX2RpZ2l0NCA9IGhtX2F2ZyRhdmVyYWdlX2htNCArIGhwcF9hdmckYXZlcmFnZV9ocHA0LAogICAgYXZnX2RpZ2l0NSA9IGhtX2F2ZyRhdmVyYWdlX2htNSArIGhwcF9hdmckYXZlcmFnZV9ocHA1CiAgICApIHw+CiAgICBzZWxlY3QoYEhpZ2hlciB0YXhvbmAsIGF2Z19kaWdpdDEsIGF2Z19kaWdpdDIsIGF2Z19kaWdpdDMsIGF2Z19kaWdpdDQsIGF2Z19kaWdpdDUpCgphdmdfZGlnaXRfbGVuZ3RocwpgYGAKCmBgYHtyfQojRVhQTE9SSU5HIENPVkFSSUFUSU9OCiMgQklQTE9UUyBGT1IgQUxMIERJR0lUUyBJTiBEQVRBU0VUIAoKI3RvIGNhbGMgcnNxdWFyZWQgCnJfc3F1YXJlZCA8LSBmdW5jdGlvbih4LCB5KSB7CiAgbW9kZWwgPC0gbG0oeSB+IHgpCiAgc3VtbWFyeShtb2RlbCkkci5zcXVhcmVkCn0KCnBhaXJzIDwtIGxpc3QoCiAgYygidG90YWxfZGlnaXQxIiwgInRvdGFsX2RpZ2l0MiIpLAogIGMoInRvdGFsX2RpZ2l0MSIsICJ0b3RhbF9kaWdpdDMiKSwKICBjKCJ0b3RhbF9kaWdpdDEiLCAidG90YWxfZGlnaXQ0IiksCiAgYygidG90YWxfZGlnaXQxIiwgInRvdGFsX2RpZ2l0NSIpLAogIGMoInRvdGFsX2RpZ2l0MiIsICJ0b3RhbF9kaWdpdDMiKSwKICBjKCJ0b3RhbF9kaWdpdDIiLCAidG90YWxfZGlnaXQ0IiksCiAgYygidG90YWxfZGlnaXQyIiwgInRvdGFsX2RpZ2l0NSIpLAogIGMoInRvdGFsX2RpZ2l0MyIsICJ0b3RhbF9kaWdpdDQiKSwKICBjKCJ0b3RhbF9kaWdpdDMiLCAidG90YWxfZGlnaXQ1IiksCiAgYygidG90YWxfZGlnaXQ0IiwgInRvdGFsX2RpZ2l0NSIpCikKCmZvciAocGFpciBpbiBwYWlycykgewogIHggPC0gYXV0b2NsZWFuW1twYWlyWzFdXV0KICB5IDwtIGF1dG9jbGVhbltbcGFpclsyXV1dCiAgcl9zcXVhcmVkIDwtIGNhbGN1bGF0ZV9yX3NxdWFyZWQoeCwgeSkKICBwIDwtIGdncGxvdChhdXRvY2xlYW4sIGFlc19zdHJpbmcoeCA9IHBhaXJbMV0sIHkgPSBwYWlyWzJdKSkgKwogICAgZ2VvbV9wb2ludCgpICsKICAgIGxhYnMoeCA9IHBhaXJbMV0sIHkgPSBwYWlyWzJdLCB0aXRsZSA9IHBhc3RlKCJCaXBsb3Qgb2YiLCBwYWlyWzFdLCAiYW5kIiwgcGFpclsyXSksIHN1YnRpdGxlID0gcGFzdGUoIlJeMiA9Iiwgcl9zcXVhcmVkKSkgKwogICAgdGhlbWVfbWluaW1hbCgpCiAgcHJpbnQocCkKfQoKYGBgCmBgYHtyfQojQ09SUkVMQVRJT04gTUFUUklYIApjb3JyZWxhdGlvbl9tYXRyaXggPC0gY29yKGF1dG9jbGVhblssIGMoInRvdGFsX2RpZ2l0MSIsICJ0b3RhbF9kaWdpdDIiLCAidG90YWxfZGlnaXQzIiwgInRvdGFsX2RpZ2l0NCIsICJ0b3RhbF9kaWdpdDUiKV0pCnByaW50KGNvcnJlbGF0aW9uX21hdHJpeCkKCmNvcnJwbG90KGNvcnJlbGF0aW9uX21hdHJpeCwgbWV0aG9kID0gImNvbG9yIiwgYWRkQ29lZi5jb2wgPSAiYmxhY2siLCB0bC5jb2wgPSAiYmxhY2siLCB0bC5zcnQgPSA0NSkKYGBgCmBgYHtyfQoKIyBGdW5jdGlvbiB0byBjYWxjdWxhdGUgUl4yCmNhbGNfcl9zcXVhcmVkIDwtIGZ1bmN0aW9uKHgsIHkpIHsKICBtb2RlbCA8LSBsbSh5IH4geCkKICBzdW1tYXJ5KG1vZGVsKSRyLnNxdWFyZWQKfQoKIyBDcmVhdGUgcGFpcnMgb2YgZGlnaXQgbGVuZ3RocwpwYWlycyA8LSBsaXN0KAogIGMoInRvdGFsX2RpZ2l0MSIsICJ0b3RhbF9kaWdpdDIiKSwKICBjKCJ0b3RhbF9kaWdpdDEiLCAidG90YWxfZGlnaXQzIiksCiAgYygidG90YWxfZGlnaXQxIiwgInRvdGFsX2RpZ2l0NCIpLAogIGMoInRvdGFsX2RpZ2l0MSIsICJ0b3RhbF9kaWdpdDUiKSwKICBjKCJ0b3RhbF9kaWdpdDIiLCAidG90YWxfZGlnaXQzIiksCiAgYygidG90YWxfZGlnaXQyIiwgInRvdGFsX2RpZ2l0NCIpLAogIGMoInRvdGFsX2RpZ2l0MiIsICJ0b3RhbF9kaWdpdDUiKSwKICBjKCJ0b3RhbF9kaWdpdDMiLCAidG90YWxfZGlnaXQ0IiksCiAgYygidG90YWxfZGlnaXQzIiwgInRvdGFsX2RpZ2l0NSIpLAogIGMoInRvdGFsX2RpZ2l0NCIsICJ0b3RhbF9kaWdpdDUiKQopCgojIEdldCB1bmlxdWUgdGF4YQp1bmlxdWVfdGF4YSA8LSB1bmlxdWUoYXV0b2NsZWFuJGBIaWdoZXIgdGF4b25gKQoKIyBmb3IgZWFjaCBoaWdoZXIgdGF4YSAKZm9yICh0YXhvbiBpbiB1bmlxdWVfdGF4YSkgewogICMgZmlsdGVyIGZvciB0aGUgY3VycmVudCBoaWdoZXIgdGF4b24KICB0YXhhX2RhdGEgPC0gYXV0b2NsZWFuW2F1dG9jbGVhbiRgSGlnaGVyIHRheG9uYCA9PSB0YXhvbiwgXQogIAogICMgZ29pbmcgdGhydSBlYWNoIGRpZ2l0IHBhaXIgCiAgZm9yIChwYWlyIGluIHBhaXJzKSB7CiAgICB4IDwtIHRheGFfZGF0YVtbcGFpclsxXV1dCiAgICB5IDwtIHRheGFfZGF0YVtbcGFpclsyXV1dCiAgICAKICAgICMgZ2V0IHJeMgogICAgcl9zcXVhcmVkIDwtIGNhbGNfcl9zcXVhcmVkKHgsIHkpCiAgICAKICAgICMgYWN0dWFsIHBsb3QKICAgIHAgPC0gZ2dwbG90KHRheGFfZGF0YSwgYWVzX3N0cmluZyh4ID0gcGFpclsxXSwgeSA9IHBhaXJbMl0pKSArCiAgICAgIGdlb21fcG9pbnQoY29sb3IgPSAiIzAwOTZGRiIsIGFscGhhID0gMC42LCBzaXplID0gMykgKwogICAgICBsYWJzKAogICAgICAgIHggPSBwYWlyWzFdLAogICAgICAgIHkgPSBwYWlyWzJdLAogICAgICAgIHRpdGxlID0gcGFzdGUoIkJpcGxvdCBvZiIsIHBhaXJbMV0sICJhbmQiLCBwYWlyWzJdLCAiZm9yIiwgdGF4b24pLAogICAgICAgIHN1YnRpdGxlID0gcGFzdGUoIlJeMiA9Iiwgcm91bmQocl9zcXVhcmVkLCAzKSkKICAgICAgKSArCiAgICAgIHRoZW1lX21pbmltYWwoKSArCiAgICAgIHRoZW1lKAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDEyLCBmYWNlID0gImJvbGQiLCBjb2xvciA9ICIjMDA5NkZGIiksCiAgICAgICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTAsIGNvbG9yID0gImJsYWNrIiksCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgZmFjZSA9ICJib2xkIiksCiAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSAxMCwgZmFjZSA9ICJib2xkIiksCiAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gIiNGRkYxRjMiKSwgIAogICAgICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUoY29sb3IgPSAid2hpdGUiKSwgCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShjb2xvciA9ICJ3aGl0ZSIpCiAgICAgICkKICAgIHByaW50KHApCiAgfQp9CgpgYGAKCmBgYHtyfQp1bmlxdWVfdGF4YSA8LSB1bmlxdWUoYXV0b2NsZWFuJGBIaWdoZXIgdGF4b25gKQoKZm9yICh0YXhvbiBpbiB1bmlxdWVfdGF4YSkgewogIHRheGFfZGF0YSA8LSBhdXRvY2xlYW5bYXV0b2NsZWFuJGBIaWdoZXIgdGF4b25gID09IHRheG9uLCBdCgogIGNvcnJlbGF0aW9uX21hdHJpeCA8LSBjb3IoYXV0b2NsZWFuWywgYygidG90YWxfZGlnaXQxIiwgInRvdGFsX2RpZ2l0MiIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidG90YWxfZGlnaXQzIiwgInRvdGFsX2RpZ2l0NCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidG90YWxfZGlnaXQ1IildKQogIHByaW50KHRheG9uKQogIHByaW50KGNvcnJlbGF0aW9uX21hdHJpeCkKICBjb3JycGxvdChjb3JyZWxhdGlvbl9tYXRyaXgsIG1ldGhvZCA9ICJjb2xvciIsIGFkZENvZWYuY29sID0gImJsYWNrIiwgdGwuY29sID0gCiAgICAgICAgICAgICAiYmxhY2siLCB0bC5zcnQgPSA0NSwgICB0aXRsZT10YXhvbiwgICAgbWFyPWMoMCwwLDEsMCkgKQp9CmBgYApgYGB7cn0KCmBgYAoK